package com.abl.core.common.util;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.Map;

/**
 * 凭证签发工具
 *
 * @author WangYongJi
 */
@Slf4j
public class JwtKit {
    //🔑HMAC 密钥长度和安全性
    //当使用基于哈希的消息验证码，例如 HS256 或 HS512 时，为了遵守 JSON Web 算法 (JWA) 规范 (RFC7518) 的严格要求，您必须使用具有相同（或更大）的密钥位长度作为输出哈希的大小。
    //这是为了避免削弱验证码的安全强度（参见 NIST 建议 NIST SP 800-117）。
    //例如，使用 HMAC256 时，密钥长度必须至少为 256 位。
    //秘钥
    private static final String secret = FileKit.fileContent(FileKit.getClassPath("secret"));

    //签名算法(HMAC256)
    private static final Algorithm algorithm256 = Algorithm.HMAC256(secret);

    //签名验证工具
    private static final JWTVerifier jwtVerifier = JWT.require(algorithm256).build();


    /**
     * 生成Token
     *
     * @param second    失效时间(秒)
     * @param jsonParam 携带参数，通过getParam方法读取参数
     * @return 生成签名字符串
     */
    public static String createToken(String jsonParam, long second) {
        JWTCreator.Builder builder = JWT.create();

        //可读取的参数信息（别存太多）
        builder.withClaim("param", jsonParam);

        //超时时间(秒)
        if (second > 0) {
            Date expireDate = new Date(new Date().getTime() + (second * 1000L));
            builder.withExpiresAt(expireDate);
        }

        return builder.sign(algorithm256);
    }

    public static String createToken(String jsonParam) {
        return createToken(jsonParam, 0L);
    }

    //检查失效
    public static void check(String token) {
        jwtVerifier.verify(token);
    }

    /**
     * 获取整个参数对象
     */
    public static JSONObject getParam(String token) {
        return JSON.parseObject(getClaims(token).get("param").asString());
    }

    /**
     * 获取指定 Key 的 Value
     */
    public static Object getParam(String token, String key) {
        return getParam(token).get(key);
    }

    //获取Claims
    private static Map<String, Claim> getClaims(String token) {
        return jwtVerifier.verify(token).getClaims();
    }

    //Token唯一标识符（可用于缓存，作强制退出登录）
    public static String tokenId(String token) {
        return jwtVerifier.verify(token).getId();
    }


//   生成256随机秘钥
//    public static void main(String[] args) {
//        System.out.println(1 / 5);
//        System.out.println(1 % 5);
//        String str1 = "1234567890";
//        String str2 = "abcdefghijklmnopqrstuvwsyz";
//        String str3 = "ABCDEFGHIJKLMNOPQRSTUVWSYZ";
//
//        StringBuilder stringBuilder = new StringBuilder();
//        for (int i = 0; i < 256; i++) {
//            if (i % 5 == 0) {
//                stringBuilder.append(str1.charAt(new Random().nextInt(9)));
//            } else if (i % 3 == 0) {
//                stringBuilder.append(str3.charAt(new Random().nextInt(25)));
//            } else {
//                stringBuilder.append(str2.charAt(new Random().nextInt(25)));
//            }
//        }
//        System.out.println(stringBuilder);
//    }

}
